Hugging Faceで学習するためにcsvファイルからDatasetDictクラスを作成する方法
こんちには。
データアナリティクス事業本部 機械学習チームの中村です。
Hugging Faceのライブラリの使い方紹介記事第1弾です。
今回は、ローカルのcsvファイルからDatasetDictクラスを作成する方法をご紹介します。
実行環境
今回はGoogle Colaboratory環境で実行しました。
ハードウェアなどの情報は以下の通りです。
- GPU: Tesla P100 (GPUメモリ16GB搭載)
- CUDA: 11.1
- メモリ: 26GB
主なライブラリのバージョンは以下となります。
- transformers: 4.22.1
- datasets: 2.4.0
インストール
transformersとdatasetsをインストールします。
!pip install transformers datasets
csvファイルの準備
適当な日本語データセットが見つけられなかったため、Hugging Faceにアップされているデータセットを取得して、一旦csvファイルに落とす形で実施したいと思います。
使用するのは以下のデータセットのうち、日本語のサブセットを使用します。
from datasets import load_dataset dataset_org = load_dataset("tyqiangz/multilingual-sentiments", "japanese")
読み込んだデータセットはDatasetDictクラスとなっています。
type(dataset_org)
datasets.dataset_dict.DatasetDict
このDatasetDictクラスをcsvから作成するのが今回やりたいことです。
まずはDatasetDictをpandasフォーマットに変換して、csvに保存します。
dataset_org.set_format(type="pandas") # pandasフォーマット変換 dataset_org["train"][:].to_csv("train.csv", index=None) # 保存 dataset_org["validation"][:].to_csv("validation.csv", index=None) dataset_org["test"][:].to_csv("test.csv", index=None) dataset_org.reset_format() # フォーマットをリセット
一応保存された中身をチェックしてみます。
!cat "train.csv" | head -n 5
text,source,label 普段使いとバイクに乗るときのブーツ兼用として購入しました。見た目や履き心地は良いです。 しかし、2ヶ月履いたらゴム底が削れて無くなりました。また、バイクのシフトペダルとの摩擦で表皮が剥がれ、本革でないことが露呈しました。ちなみに防水とも書いていますが、雨の日は内部に水が染みます。 安くて見た目も良く、履きやすかったのですが、耐久性のなさ、本革でも防水でも無かったことが残念です。結局、本革の防水ブーツを買い直しました。,amazon_reviews_multi,2 十分な在庫を用意できない販売元も悪いですが、Amazonやら楽⚪︎が転売を認めちゃってるのが結果的に転売の後押しになっちゃってるんだよなぁ… Amazonもここぞとばかりに抱き合わせ販売しまくるし… それを恥ずかしいと思えなくなったら動物と同じですよ、最大手さん。,amazon_reviews_multi,2 見た目はかなりおしゃれで気に入りました。2、3回持ち歩いた後いつも通りゼンマイを巻いていたら突然空回り。 針の調整はできるけど、つまみをあげても下げてもゼンマイを巻くことができず。 時計屋に持って行って中を開けてもらったら、中のケースと外側の規格がそもそも合っていないため、固定されず、一度ズレると噛み合わなくなるんだそう。 返品して交換した方がいいと言われましたが、保証書付いてないし、 クーリングオフ期間もとっくに過ぎています。 アンティーク感覚で家で放置するならおススメですが、 本来の用途としては全く使えません。 ご注意を。,amazon_reviews_multi,2 よくある部分での断線はしませんでした ただiphoneとの接続部で接触不良、折れました iphoneの中に残されてしまい摘出に苦労しました,amazon_reviews_multi,2
きちんとcsvファイルが保存されています。
csvファイルの読み込み(直接)
最初に結論ですが、csvファイルから直接読み込む方法は以下となります。
dataset_files = { "train": ["train.csv"], "validation": ["validation.csv"], "test": ["test.csv"], } dataset1 = load_dataset("csv", data_files=dataset_files)
こちらは、公式ドキュメントにも明記されています。
csvファイルの読み込み(pandas経由)
また前処理としてpandas等で処理を行いたいケースもあるかと思います。 その場合も見ていきます。
まずはpandasのDataFrameとして読み込みをします。
import pandas as pd train_df = pd.read_csv("train.csv") validation_df = pd.read_csv("validation.csv") test_df = pd.read_csv("test.csv")
次に、Datasetクラスに変換します。
from datasets import Dataset train_dataset = Dataset.from_pandas(train_df) validation_dataset = Dataset.from_pandas(validation_df) test_dataset = Dataset.from_pandas(test_df)
最後に、DatasetDictを作成します。
from datasets import DatasetDict dataset = DatasetDict({ "train": train_dataset, "validation": validation_dataset, "test": test_dataset, })
ほぼ以上でcsvファイルからの読み込みはできているのですが、実際はまだオリジナルと少し差異があります。
次でその差異を埋めていきます。
labelカラムをClassLabelにキャスト
差異をみるために、Datasetクラスのfeaturesを確認してみましょう。
まずはオリジナルからです。
dataset_org["train"].features
{'text': Value(dtype='string', id=None), 'source': Value(dtype='string', id=None), 'label': ClassLabel(names=['positive', 'neutral', 'negative'], id=None)}
labelがClassLabelクラスとなっていることが分かります。
次に、csvファイルから作成したものを見てみましょう。
dataset["train"].features
{'text': Value(dtype='string', id=None), 'source': Value(dtype='string', id=None), 'label': Value(dtype='int64', id=None)}
labelが通常のint64になっていることが分かります。
このままでも問題ないケースもありますが、同一にするためには以下のようなキャスト処理が必要です。
# ClassLabelクラスに変換 class_label = ClassLabel(num_classes=3, names=['positive', 'neutral', 'negative']) dataset = dataset.cast_column("label", class_label)
dataset["train"].features
{'text': Value(dtype='string', id=None), 'source': Value(dtype='string', id=None), 'label': ClassLabel(names=['positive', 'neutral', 'negative'], id=None)}
DatasetDictクラスが完成すれば、あとはtokenizeやtrainerの処理をこのクラスの状態で扱うことができるので、便利です。
これ以降のtokenizeやtrainerについては以下の過去記事を参考にされてください。
まとめ
いかがでしたでしょうか?
csvファイルからの読み込み自体は公式ドキュメントに記載があるのですが、 DatasetクラスからDatasetDictクラスを作成する方法や、ClassLabelにキャストする方法は読み解くのに苦労しましたので、今回記事にさせていただきました。 ここまでデータセットを整えることで、後々の学習処理などがやりやすくなると思います。
本記事がHuggin Faceを使われる方の参考になれば幸いです。